package com.hh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hh.entity.domain.ArticleViews;
import com.hh.entity.domain.Blog;
import com.hh.mapper.ArticleViewsMapper;
import com.hh.service.ArticleViewsService;
import com.hh.service.BlogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @author hanhui
 * @description 针对表【article_views】的数据库操作Service实现
 * @createDate 2025-05-31 21:01:54
 */
@Service
@Slf4j
public class ArticleViewsServiceImpl extends ServiceImpl<ArticleViewsMapper, ArticleViews>
        implements ArticleViewsService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    @Lazy
    private BlogService blogService;

    //构造函数
    @Override
    public void incrementViewCount(Long articleId, String userKey) {
        String redisUserKey = "view:" + articleId + ":" + userKey;
        String redisCountKey = "view:" + articleId;

        // 检查是否重复访问
        Boolean isNewVisit = stringRedisTemplate.opsForValue().setIfAbsent(redisUserKey, "1", 60, TimeUnit.SECONDS);
        if (isNewVisit != null && isNewVisit) {
            // 新访问，增加计数
            stringRedisTemplate.opsForValue().increment(redisCountKey);
            // 异步同步到数据库
            syncViewCountToDb(articleId, redisCountKey);
            blogService.updateBlogHotScore(articleId);
        }
    }

    @Override
    public Long getViewCount(Long articleId) {
        String redisCountKey = "view:" + articleId;
        String countStr = stringRedisTemplate.opsForValue().get(redisCountKey);
        if (countStr != null) {
            return Long.valueOf(countStr);
        }
        QueryWrapper<ArticleViews> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("articleId", articleId);
        ArticleViews articleViews = this.getOne(queryWrapper);
        return articleViews != null ? articleViews.getViewCount() : 0L;
    }

    @Async("viewSyncExecutor")
    public void syncViewCountToDb(Long blogId, String redisKey) {
        try {
            // 延迟1秒，批量处理
            Thread.sleep(1000);

            String countStr = stringRedisTemplate.opsForValue().get(redisKey);
            if (countStr != null) {
                Long count = Long.valueOf(countStr);
                // 使用MyBatis-Plus的内置方法或自定义SQL更新
                Blog blog = new Blog();
                blog.setId(blogId);
                blog.setViewCount(count);
                blogService.updateById(blog);
            }
        } catch (Exception e) {
            log.error("同步浏览量到数据库失败: {}", e.getMessage(), e);
        }
    }
}




